home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Multimedia Plus
/
Multimedia Plus with ClearVue Version 10-94 (Knowledge Media Inc.).ISO
/
dos
/
anim
/
flilib
/
flisrc
/
lccomp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-11-17
|
4KB
|
162 lines
/* fii_lccomp.c - Some C code that mixes with the assembler code in
comp.asm and skip.asm to make up compressed pixel packets suitable
for incorporation into a FLI file. See also writefli.c */
#include "aai86.h"
#include "aaflisav.h"
#include "aafii.h"
#define INERTIA 4
static char *
sbrc_line(s1, s2, cbuf, count)
Pixel *s1, *s2, *cbuf;
int count;
{
register int wcount;
int i;
register char *c;
int op_count;
int same_count;
int next_match;
int bcount;
op_count = 0;
c = cbuf+1;
for (;;)
{
if (count <= 0)
{
goto OUT;
}
/* first find out how many bytes to skip... */
wcount = i86_bcompare(s1, s2, count);
if ((count -= wcount) <= 0)
goto OUT; /* same until the end... */
/* if skip is longer than 255 have to break it up into smaller ops */
while (wcount > 255)
{
s1 += 255+1;
s2 += 255;
wcount -= 255+1;
/* make dummy copy 1 op */
*c++ = 255;
*c++ = 1;
*c++ = *s2++;
op_count++;
}
/* save initial skip and move screen pointer to 1st different byte */
*c++ = wcount;
s1 += wcount;
s2 += wcount;
op_count++;
/* if have skipped to near the end do a literal copy... */
if (count <= INERTIA)
{
*c++ = count;
i86_bcopy(s2,c,count);
c += count;
goto OUT;
}
/* now look for a run of same... */
bcount = count;
if (bcount > FLI_MAX_RUN)
bcount = FLI_MAX_RUN;
wcount = i86_bsame(s2, bcount);
if (wcount >= INERTIA) /* it's worth doing a same thing thing */
{
next_match = fii_tnskip(s1, s2, wcount,INERTIA);
if (next_match < wcount) /* if it's in our space and a decent size */
{ /* we'll cut short same run for the skip */
wcount = next_match;
}
*c++ = -wcount;
*c++ = *s2;
s1 += wcount;
s2 += wcount;
count -= wcount;
}
else /* doing a literal copy. What can we do to make it short? */
{
/* figure out how long until the next worthwhile "skip" */
/* Have wcount of stuff we can't skip through. */
wcount = fii_tnsame(s2,fii_tnskip(s1,s2,bcount,INERTIA-1),INERTIA);
/* Say copy positive count as lit copy op, and put bytes to copy
into the compression buffer */
*c++ = wcount;
i86_bcopy(s2,c,wcount);
s1 += wcount;
s2 += wcount;
c += wcount;
count -= wcount;
}
}
OUT:
*cbuf = op_count;
return(i86_norm_ptr(c));
}
Cbuf *fii_lccomp(Pixel *s1,Pixel *s2,USHORT *cbuf,int width,int height)
{
int skip_count, lcount, j;
Pixel *c;
Pixel *oc;
unsigned acc;
long total;
unsigned last_real;
/* find out how many lines of s1 and s2 are the same */
acc = (width>>1); /* SHORTS in line */
j = height;
skip_count = 0;
total = 0;
while (--j >= 0)
{
if (i86_wcompare(s1, s2, acc) != acc)
break;
s1 += width;
s2 += width;
skip_count++;
}
/* If all same do special case for empty frame*/
if (skip_count == height)
return((Cbuf *)(cbuf+1));
/* store offset of 1st real line and set up for main line-at-a-time loop */
*cbuf++ = skip_count;
height -= skip_count;
c = (char *)(cbuf+1);
last_real = 0; /* keep track of last moving line */
for (j=1; j<=height;j++)
{
oc = c;
if (i86_wcompare(s1,s2,acc) == acc) /* whole line is the same */
{
*c++ = 0; /* set op count to 0 */
}
else /* compress line */
{
c = sbrc_line(s1,s2,c,width);
last_real = j;
}
total += i86_ptr_to_long(c) - i86_ptr_to_long(oc);
if (total >= 60000L)
return(NULL);
s1 += width;
s2 += width;
}
/* set # of lines in compression to last real, removing empty bottom lines
from buffer */
*cbuf = last_real;
c -= height-last_real;
return(i86_enorm_ptr(c));
}